/**
 * 认证状态管理 Store
 */

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
import { ElMessage } from 'element-plus'
import { authService } from '@/services/auth'
import { tokenUtils, userUtils, rememberMe, formatErrorMessage } from '@/utils/auth'
import type { 
  AuthState, 
  UserInfo, 
  LoginRequest, 
  RegisterRequest, 
  ResetPasswordRequest,
  SendCodeRequest,
  LoginResponse 
} from '@/types'

/**
 * 认证状态管理
 */
export const useAuthStore = defineStore('auth', () => {
  // 状态
  const isAuthenticated = ref<boolean>(false)
  const accessToken = ref<string | null>(null)
  const refreshToken = ref<string | null>(null)
  const tokenType = ref<string>('Bearer')
  const expiresAt = ref<number | null>(null)
  const userInfo = ref<UserInfo | null>(null)
  const loading = ref<boolean>(false)

  // 计算属性
  const isTokenExpired = computed(() => {
    if (!expiresAt.value) return true
    // 提前 5 分钟判断过期
    const fiveMinutes = 5 * 60 * 1000
    return Date.now() >= (expiresAt.value - fiveMinutes)
  })

  const hasUserInfo = computed(() => {
    return userInfo.value !== null
  })

  const userDisplayName = computed(() => {
    if (!userInfo.value) return ''
    return userInfo.value.nickname || userInfo.value.username || userInfo.value.email
  })

  const userAvatar = computed(() => {
    return userInfo.value?.avatar || ''
  })

  /**
   * 初始化认证状态
   */
  const initAuth = async (): Promise<void> => {
    try {
      // 从本地存储恢复状态
      const storedAccessToken = tokenUtils.getAccessToken()
      const storedRefreshToken = tokenUtils.getRefreshToken()
      const storedTokenType = tokenUtils.getTokenType()
      const storedExpiresAt = tokenUtils.getExpiresAt()
      const storedUserInfo = userUtils.getUserInfo()

      if (storedAccessToken && storedRefreshToken && storedUserInfo) {
        accessToken.value = storedAccessToken
        refreshToken.value = storedRefreshToken
        tokenType.value = storedTokenType
        expiresAt.value = storedExpiresAt
        userInfo.value = storedUserInfo
        isAuthenticated.value = true

        // 检查令牌是否过期
        if (isTokenExpired.value) {
          await handleRefreshToken()
        } else {
          // 验证令牌有效性
          const isValid = await authService.validateToken()
          if (!isValid) {
            await logout()
          }
        }
      }
    } catch (error) {
      console.error('Failed to initialize auth:', error)
      await logout()
    }
  }

  /**
   * 用户登录
   */
  const login = async (loginData: LoginRequest): Promise<void> => {
    try {
      loading.value = true
      
      const response: LoginResponse = await authService.login(loginData)
      
      // 保存认证信息
      await setAuthData(response, loginData.rememberMe)
      
      ElMessage.success('登录成功')
    } catch (error) {
      const message = formatErrorMessage(error)
      ElMessage.error(message)
      throw error
    } finally {
      loading.value = false
    }
  }

  /**
   * 用户注册
   */
  const register = async (registerData: RegisterRequest): Promise<void> => {
    try {
      loading.value = true
      
      await authService.register(registerData)
      
      ElMessage.success('注册成功，请登录')
    } catch (error) {
      const message = formatErrorMessage(error)
      ElMessage.error(message)
      throw error
    } finally {
      loading.value = false
    }
  }

  /**
   * 用户登出
   */
  const logout = async (showMessage: boolean = true): Promise<void> => {
    try {
      // 调用登出接口
      if (isAuthenticated.value) {
        await authService.logout()
      }
    } catch (error) {
      console.warn('Logout API call failed:', error)
    } finally {
      // 清除本地状态
      clearAuthData()
      
      if (showMessage) {
        ElMessage.success('已退出登录')
      }
    }
  }

  /**
   * 刷新令牌
   */
  const handleRefreshToken = async (): Promise<void> => {
    try {
      if (!refreshToken.value) {
        throw new Error('No refresh token available')
      }

      const response: LoginResponse = await authService.refreshToken(refreshToken.value)
      
      // 更新认证信息
      await setAuthData(response, rememberMe.getRememberMe())
    } catch (error) {
      console.error('Failed to refresh token:', error)
      await logout(false)
      throw error
    }
  }

  /**
   * 重置密码
   */
  const resetPassword = async (resetData: ResetPasswordRequest): Promise<void> => {
    try {
      loading.value = true
      
      await authService.resetPassword(resetData)
      
      ElMessage.success('密码重置成功，请使用新密码登录')
    } catch (error) {
      const message = formatErrorMessage(error)
      ElMessage.error(message)
      throw error
    } finally {
      loading.value = false
    }
  }

  /**
   * 发送验证码
   */
  const sendVerificationCode = async (codeData: SendCodeRequest): Promise<void> => {
    try {
      await authService.sendVerificationCode(codeData)
      
      ElMessage.success('验证码发送成功')
    } catch (error) {
      const message = formatErrorMessage(error)
      ElMessage.error(message)
      throw error
    }
  }

  /**
   * 获取用户信息
   */
  const fetchUserInfo = async (): Promise<void> => {
    try {
      const userData = await authService.getUserInfo()
      userInfo.value = userData
      userUtils.setUserInfo(userData)
    } catch (error) {
      const message = formatErrorMessage(error)
      ElMessage.error(message)
      throw error
    }
  }

  /**
   * 更新用户信息
   */
  const updateUserInfo = async (userData: Partial<UserInfo>): Promise<void> => {
    try {
      loading.value = true
      
      const updatedUserInfo = await authService.updateUserInfo(userData)
      userInfo.value = updatedUserInfo
      userUtils.setUserInfo(updatedUserInfo)
      
      ElMessage.success('用户信息更新成功')
    } catch (error) {
      const message = formatErrorMessage(error)
      ElMessage.error(message)
      throw error
    } finally {
      loading.value = false
    }
  }

  /**
   * 修改密码
   */
  const changePassword = async (passwordData: {
    oldPassword: string
    newPassword: string
    confirmPassword: string
  }): Promise<void> => {
    try {
      loading.value = true
      
      await authService.changePassword(passwordData)
      
      ElMessage.success('密码修改成功')
    } catch (error) {
      const message = formatErrorMessage(error)
      ElMessage.error(message)
      throw error
    } finally {
      loading.value = false
    }
  }

  /**
   * 上传头像
   */
  const uploadAvatar = async (file: File): Promise<void> => {
    try {
      loading.value = true
      
      const avatarUrl = await authService.uploadAvatar(file)
      
      if (userInfo.value) {
        userInfo.value.avatar = avatarUrl
        userUtils.setUserInfo(userInfo.value)
      }
      
      ElMessage.success('头像上传成功')
    } catch (error) {
      const message = formatErrorMessage(error)
      ElMessage.error(message)
      throw error
    } finally {
      loading.value = false
    }
  }

  /**
   * 设置认证数据
   */
  const setAuthData = async (response: LoginResponse, remember: boolean = false): Promise<void> => {
    accessToken.value = response.accessToken
    refreshToken.value = response.refreshToken
    tokenType.value = response.tokenType
    userInfo.value = response.userInfo
    isAuthenticated.value = true

    // 计算过期时间戳
    const expiresAtTimestamp = Date.now() + (response.expiresIn * 1000)
    expiresAt.value = expiresAtTimestamp

    // 保存到本地存储
    tokenUtils.setAccessToken(response.accessToken)
    tokenUtils.setRefreshToken(response.refreshToken)
    tokenUtils.setTokenType(response.tokenType)
    tokenUtils.setExpiresAt(expiresAtTimestamp)
    userUtils.setUserInfo(response.userInfo)
    rememberMe.setRememberMe(remember)
  }

  /**
   * 清除认证数据
   */
  const clearAuthData = (): void => {
    isAuthenticated.value = false
    accessToken.value = null
    refreshToken.value = null
    tokenType.value = 'Bearer'
    expiresAt.value = null
    userInfo.value = null

    // 清除本地存储
    tokenUtils.clearTokens()
    userUtils.clearUserInfo()
    rememberMe.clearRememberMe()
  }

  /**
   * 检查权限
   */
  const hasPermission = async (permission: string): Promise<boolean> => {
    try {
      return await authService.hasPermission(permission)
    } catch (error) {
      return false
    }
  }

  /**
   * 检查角色
   */
  const hasRole = async (role: string): Promise<boolean> => {
    try {
      return await authService.hasRole(role)
    } catch (error) {
      return false
    }
  }

  // 导出状态和方法
  return {
    // 状态
    isAuthenticated,
    accessToken,
    refreshToken,
    tokenType,
    expiresAt,
    userInfo,
    loading,

    // 计算属性
    isTokenExpired,
    hasUserInfo,
    userDisplayName,
    userAvatar,

    // 方法
    initAuth,
    login,
    register,
    logout,
    refreshTokenAction: handleRefreshToken,
    resetPassword,
    sendVerificationCode,
    fetchUserInfo,
    updateUserInfo,
    changePassword,
    uploadAvatar,
    hasPermission,
    hasRole,
    clearAuthData
  }
})
